/**
 * 
 */
package com.tc.report;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.tc.report.intersect.IntersectReportImpl;

/**
 * 
 * 报表区域中字段值的节点信息。
 * @author shy
 *
 */
public class ReportValueNote {
	private String code;//当前节点的值。
	private String fieldName;//当前节点值所在的字段名称。
	private ReportField reportField;//当前字段对象。
	private String parentCode;//父节点信息。
	private int level = 0;//树型结点从1开始.
	private int orderNo=0;//同层次的节点顺序。
	private ReportAreaHandle areaHandle;
	/**当前节点的子节点信息 */
	private List<ReportValueNote> sonList = new ArrayList<ReportValueNote>();
	/**
	 * 保存当前节点值所包含的行结果集列表。
	 */
	private List<Map<String,Object>> queryResultList = new ArrayList<Map<String,Object>>();
	
	/**
	 * 保存当前节点值所包含的行结果集列表,当前节点如果存在字段项，则已经转换成字典名称。
	 */
	private List<Map<String,Object>> resultList = new ArrayList<Map<String,Object>>();
	
	
	public void initNodeResultList(){
		queryResultList = new ArrayList<Map<String,Object>>();
		resultList = new ArrayList<Map<String,Object>>();
	}
	
	
	public List<Map<String, Object>> getResultList() {
		return resultList;
	}

	public ReportValueNote(){
		
	}
	
	/**
	 * 用于判断当前字段的值是否显示增加 合计单元.
	 * @return
	 */
	public boolean isShowTotalCell(){
		boolean isShow = false;
		if(this.reportField==null){//防错
			return isShow;
		}
		String nextFieldName = this.reportField.getNextFieldName();
		if(StringUtils.isBlank(nextFieldName)){//如果是最后一个字段,也不需要显示显示合计单元.
			isShow = false;
			return isShow;
		}
		return this.reportField.isShowTotal();
	}
	
	/**
	 * 将结果集对应字段的值为当前值的行结果集加入本节点信息。
	 * @param queryResult
	 */
	public void addQueryResult(Map<String,Object> queryResult){
		this.queryResultList.add(queryResult);
	}
	
	
	public List<Map<String, Object>> getQueryResultList() {
		return queryResultList;
	}

	/**
	 * 加载数值，主要构建树型节点信息。
	 * @throws Exception
	 */
	public void loadQueryResult() throws Exception{
		if(reportField==null){
			throw new Exception("不存在当前字段对象!");
		}
		/**
		 * 获取下一字段信息，如果存在下一字段，说明不是最后一个字段。需要递归处理 。
		 */
		String nextFieldName = reportField.getNextFieldName();
		if (StringUtils.isNotBlank(nextFieldName)) {// 如果存在下个字段，则进行处理 。
			ReportField nextField = areaHandle.getReportField(nextFieldName);
			int orderIndex = 1;
			/**
			 * 保存下一字段不同的字段值信息，即当前节点的子节点信息。
			 */
			Map<String, ReportValueNote> valueNoteMap = new HashMap<String, ReportValueNote>();
			for (Map<String, Object> queryResult : queryResultList) {
				String fieldValue = StringUtils.objToString(queryResult.get(nextFieldName));
				ReportValueNote valueNote = valueNoteMap.get(fieldValue);
				if (valueNote == null) {
					valueNote = new ReportValueNote(this.areaHandle);
					valueNote.setCode(fieldValue);
					valueNote.setFieldName(nextFieldName);
					valueNote.setReportField(nextField);
					valueNote.setParentCode(this.code);
					valueNote.setLevel(this.level + 1);// 从1开始
					valueNote.setOrderNo(orderIndex++);
					valueNoteMap.put(fieldValue, valueNote);
					sonList.add(valueNote);
				}
				valueNote.addQueryResult(queryResult);// 将当前行结果集加入该值节点中。
			}
			Map<String, Object> fieldDict = nextField.getFieldDict();
			//处理字典项的值。
			for (Map<String, Object> queryResult : resultList) {
				String fieldValue = StringUtils.objToString(queryResult.get(nextFieldName));
				String dictName = fieldDict.get(fieldValue)==null?fieldValue:(String)fieldDict.get(fieldValue);
				ReportValueNote valueNote = valueNoteMap.get(fieldValue);
				queryResult.put(nextFieldName, dictName);
				valueNote.getResultList().add(queryResult);
			}
		}
		/** 递归处理子节点信息 */
		for (ReportValueNote valueNote : sonList) {
			valueNote.loadQueryResult();
		}
	}
	
	/**
	 * 计算当前节点的跨度（行区域为纵向跨度rowSpan,列区域为横向跨度colSpan）
	 * @param  isHaveValueField 判断当前区域是否包括存在多个值字段时的数据显示。
	 * @return 当前节点的跨度
	 * @throws Exception
	 */
	public int getSpanOfCurNode(boolean isHaveValueField,boolean isSelfNode) throws Exception{
		IntersectReportImpl reportManage = areaHandle.getReportManage();
		int multiple = reportManage.getMultipleOfValArea(isHaveValueField);
		if(this.sonList.size()==0){
			return 1 * multiple;//如果为最后一个字段，返回1*multiple即可.
		}
		int spanSize = 0;
		boolean showTotal = reportField.isShowTotal();//判断当前字段是否显示合计值。这里已确认存在子节点的情况.
		for(ReportValueNote note : this.sonList){
			spanSize += note.getSpanOfCurNode(isHaveValueField,false);
		}
		if(showTotal&&!isSelfNode){//子节点结束后增加合计行,如果是传入结点自身,则不需要计算合计行.
			spanSize += multiple;//增加合计行。这里不需要考虑合计行是否在前还是在后。
		}
		return spanSize;
	}
		
	public ReportValueNote(ReportAreaHandle areaHandle){
		this.areaHandle = areaHandle;
	}

	public String getCode() {
		return code;
	}
	//获取最终的显示值.主要用于字典转换.
	public String getDisValue(){
		String disValue = this.code;
		if(this.reportField==null){
			disValue = this.code;
		}
		Map<String, Object> fieldDict = this.reportField.getFieldDict();
		if(fieldDict==null){
			disValue = this.code;
		}
		disValue = (String)fieldDict.get(this.code);
		if(StringUtils.isBlank(disValue)){
			disValue = this.code;
		}
		return disValue;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getFieldName() {
		return fieldName;
	}

	public void setFieldName(String fieldName) {
		this.fieldName = fieldName;
	}

	public String getParentCode() {
		return parentCode;
	}

	public void setParentCode(String parentCode) {
		this.parentCode = parentCode;
	}

	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public int getOrderNo() {
		return orderNo;
	}

	public void setOrderNo(int orderNo) {
		this.orderNo = orderNo;
	}

	public ReportAreaHandle getAreaHandle() {
		return areaHandle;
	}

	public void setAreaHandle(ReportAreaHandle areaHandle) {
		this.areaHandle = areaHandle;
	}

	public List<ReportValueNote> getSonList() {
		return sonList;
	}

	public ReportField getReportField() {
		return reportField;
	}
	public void setReportField(ReportField reportField) {
		this.reportField = reportField;
	}
	
	
}
